<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>JS执行机制</title>
    <style>
        .红色标注 {
            color: red;
        }
        a{
            font-size: 20px;
        }
    </style>
</head>
<body>
<h2>JS 执行机制</h2>
<p>
    JavaScript 语言的一大特点就是 单线程，也就是说，同一个时间只能做一件事。 <br>
    这是因为 Javascript 这门脚本语言诞生的使命所致——JavaScript 是为处理页面中用户的交互，以及操作 DOM 而诞生的。 <br>
    比如我们对某个 DOM 元素进行添加和删除操作，不能同时进行。 应该先进行添加，之 后再删除。
</p>
<p>
    单线程就意味着，所有任务需要排队，前一个任务结束，才会执行后一个任务。这样所导致的问题是： <br>
    如果 JS 执行的时间过长，这样就会造成页面的渲染不连贯，导致页面渲染加载阻塞的感觉
</p>
<hr>

<p>
    为了解决这个问题，利用多核 CPU 的计算能力，HTML5 提出 Web Worker 标准 <br>
    允许 JavaScript 脚本创建多个 线程。于是，JS 中出现了 同步和异步。
</p>
<h3>同步</h3>
<p>
    前一个任务结束后再执行后一个任务，程序的执行顺序与任务的排列顺序是一致的、同步的。 <br>
    比如做饭的同步做法：我们要烧水煮饭，等水开了（10分钟之后），再去切菜，炒菜。
</p>
<h3>异步</h3>
<p>
    你在做一件事情时，因为这件事情会花费很长时间，在做这件事的同时，你还可以去处理其他事情。 <br>
    比如做饭的异步做法，我们在烧水的同时，利用这10分钟，去切菜，炒菜。
</p>
<p class="红色标注">他们的本质区别： 这条流水线上各个流程的执行顺序不同。</p>
<hr>

<h3>同步任务</h3>
<p>
    同步任务都在主线程上执行，形成一个执行栈
</p>
<h3>异步任务</h3>
<p>
    JS 的异步是通过回调函数实现的。 <br>
    一般而言，异步任务有以下三种类型: <br>
    1、普通事件，如 click、resize 等 <br>
    2、资源加载，如 load、error 等 <br>
    3、定时器，包括 setInterval、setTimeout 等 <br>
    异步任务相关添加到任务队列中（任务队列也称为消息队列）。
</p>
<hr>

<h3>执行顺序:</h3>
<p>
    1. 先执行 执行栈 中的同步任务。 <br>
    2. 异步任务放入 任务队列 中。 <br>
    3. 一旦执行栈中的所有同步任务执行完毕，系统就会按次序读取任务队列中的异步任务， <br>
    于是被读取的异步任务结束等待状态，进入执行栈，开始执行
</p>
<hr>
<img src="./素材/JS执行机制.png" alt="">
<p>由于主线程不断的重复获得任务、执行任务、再获取任务、再执行，所以这种机制被称为 事件循环(event loop)</p>
<hr>
<a href="https://www.bilibili.com/video/BV1Y84y1L7Nn/?p=128&spm_id_from=pageDriver&vd_source=cb928a955f1123af004a2e3158113ea7">
    JS执行机制 教程视频讲解
</a>



<script>
    // 这里是 事件循环 演示
    console.log(1)
    console.log(2)
    // 延时器, 延时设置 0
    setTimeout(function () {
        console.log(3)
    }, 0)
    console.log(4);

    // 以上输出结果是多少?  控制台信息是 1 2 4 3
    // 因为延时器是 异步任务里的, 一定要执行完 同步任务,才在执行 异步任务
</script>
</body>
</html>